package com.prabhakar.taxiclubapp;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.maps.model.LatLng;
import com.util.taxiclubapp.GPSChecker;
import com.util.taxiclubapp.GeoCode;

public class BookingSummaryActivity extends Activity {

	private static final String TAG ="BookingSummaryActivity ";
	JSONParser jsonParser = new JSONParser();

	GMapV2Direction md;
	JSONObject jsonObj;
	String name="";
	String phoneNumber = "";
	String pickUpLocation = "";
	String dropLocation = "";
	String email = "";
	String carType = "";
	String pickUpDate = "";
	String pickupTime = "";
	String noOfPassengers = "";

	LatLng sourceLatlng = null;
	LatLng destinationLatlng = null;

	Bundle b = null;
	//	Button nextPageButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//	setContentView(R.layout.booking_summary);
		setContentView(R.layout.booking_summary);

		b = getIntent().getExtras();
		try {
			jsonObj = new JSONObject(b.getString("bookingDetails"));
			if(jsonObj!=null){
				name= jsonObj.getString(Constants.NAME);
				phoneNumber = jsonObj.getString(Constants.PHONENUMBER);
				email = jsonObj.getString(Constants.EMAIL);
				pickUpLocation = jsonObj.getString(Constants.PICKUP_LOCATION);
				dropLocation = jsonObj.getString(Constants.DROP_LOCATION);
				pickUpDate = jsonObj.getString(Constants.PICKUP_DATE);
				pickupTime= jsonObj.getString(Constants.PICKUP_TIME);
				noOfPassengers= jsonObj.getString(Constants.NO_OF_PASSENGERS);
				carType = jsonObj.getString(Constants.CARTYPE);

			}
		} catch (JSONException e) {
			e.printStackTrace();
		}

		Log.v(TAG,"name > "+name +"phoneNumber > "+phoneNumber +"email > "+email+"pickUpLocation > "+pickUpLocation +"destination > "+dropLocation);
		Log.v(TAG,"pickUpDate > "+pickUpDate +"pickupTime > "+pickupTime +"noOfPassengers > "+noOfPassengers);
		Log.v(TAG,"carType > "+carType);

		if(dropLocation.length()!=0 && pickUpLocation.length()!=0){
			//get latlng for both....
			//check GPS connections here ...else do ALERT USER TO SWTICH ON the same..
			if(isInternetOn()){
				GeoCode gc = new GeoCode();
				sourceLatlng = getLocationFromAddress(pickUpLocation);		
				destinationLatlng = getLocationFromAddress(dropLocation);
			}
			Toast.makeText(this,"sourceLatlng = "+sourceLatlng+ " destinationLatlng = "+destinationLatlng , Toast.LENGTH_LONG).show();
			Log.v(TAG ,"sourceLatlng = "+sourceLatlng+ " destinationLatlng = "+destinationLatlng );
		}else{
			Toast.makeText(this, Constants.ImProperLocations_For_GMap , Toast.LENGTH_LONG).show();
			finish();
		}

		if(sourceLatlng != null && destinationLatlng != null){
			if(isInternetOn()){
				new getRouteDuration().execute();
			}
		}else{
			finish();
		}


		// NEXT BUTTON -onclick -code ----to goto ShowMap Page..
		Button nextPageButton = (Button)findViewById(R.id.gotoShowMapPage);
		nextPageButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// call a  method thts redirects to Show Map Page...
				if(isInternetOn()){
					showMapRoute(b);
				}
			}
		});


		// NEXT BUTTON -onclick -code ----to goto AsyncBookingRequest..
		Button confirmBooking = (Button)findViewById(R.id.confirmBooking);
		confirmBooking.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if(isInternetOn()){
					new AsyncBookingRequest().execute();	
				}
			}
		});

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.booking_summary, menu);
		return true;
	}
	
	
	/*
	 * This method does check-  ARE WE CONNECTED TO THE NET
	*/
	public final boolean isInternetOn()
	{
		String title,message="";
		boolean connected = false;
		ConnectivityManager connec = (ConnectivityManager)
	    getSystemService(Context.CONNECTIVITY_SERVICE);

	  if (connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState() == NetworkInfo.State.CONNECTED ||
			  connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState() == NetworkInfo.State.CONNECTED ){
		 
		  // MESSAGE TO SCREEN FOR TESTING (IF REQ)
		  title="Internet ENABLED";
		  message ="Internet is  enabled.";
		//  GPSChecker.showAlertDialog(this, title, message);
		  connected = true;
	 
	  }else if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED
			  ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED  ){
		  
		  connected =  false;
		  title= Constants.INTERNET_DISABLED_TITLE ;
		  message = Constants.INTERNET_DISABLED_MESSAGE ;
		  GPSChecker.showAlertDialog(this, title, message);
	  }
	  return connected;
	}
	

	/*
	 *  This method returns the latLng for the Address String..
	 */	
	private LatLng getLocationFromAddress(String address){
			
			LatLng latlng = null;
			List<Address> addressList = null;
			try {
				 Geocoder geo = new Geocoder(getApplicationContext()); 				//Geocoder(this,Locale.getDefault());
				addressList = geo.getFromLocationName(address, 5);

				if(addressList!=null && addressList.size()>0){
					
					double lng = addressList.get(0).getLongitude();
					double lat = addressList.get(0).getLatitude();
				//	System.out.println(" GeoCode -lat >>"+lat);
				//	System.out.println(" GeoCode -lang >>"+lng);
					latlng = new LatLng(lat,lng);
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}catch(Exception e1){
				System.out.println("e1.getMessage() >>>"+e1.getMessage());
				e1.printStackTrace();
			}
			
			return latlng;
		}
	
	
	private void showBookingSummary(int routeLength ,int routeTime){

		double fare = 0;

		String routeTimeToBeDisplayed = Constants.getRouteTimeInStringFormat(routeTime);
		String routeDistanceToBeDisplayed = routeLength + "Kms";

		Toast.makeText(BookingSummaryActivity.this," Estimated DISTANCE IN kms >>"+routeLength , Toast.LENGTH_LONG).show();
		Toast.makeText(BookingSummaryActivity.this,"Estimated TIME DURATION >>"+routeTimeToBeDisplayed , Toast.LENGTH_LONG).show();

		//DISPLAY BOOKING SUMMARY---making use of RouteLength && RouteTime as well ...alongwith - PickUpLOc ,DropLoc, PickupTime

		TextView summary_pickupLoc = (TextView)findViewById(R.id.summary_pickupLoc);
		summary_pickupLoc.setText(pickUpLocation);

		TextView summary_dropLoc = (TextView)findViewById(R.id.summary_dropLoc);
		summary_dropLoc.setText(dropLocation);

		TextView summary_pickupTime = (TextView)findViewById(R.id.summary_pickupTime);
		String pickUpTime_toBeDisplayed = getpickUpTime_toBeDisplayed(pickupTime);	//pickupTime
		summary_pickupTime.setText(pickUpTime_toBeDisplayed);

		TextView estdDist = (TextView)findViewById(R.id.route_distance);
		estdDist.setText(routeDistanceToBeDisplayed);

		TextView route_time = (TextView)findViewById(R.id.route_time);
		route_time.setText(routeTimeToBeDisplayed);

		TextView route_fare = (TextView)findViewById(R.id.summary_fare);
		fare = getRouteFare(routeLength);
		route_fare.setText(""+fare);

	}

	private String getpickUpTime_toBeDisplayed(String pickupTime2) {

		String returnString = "";
		if(!pickupTime2.equalsIgnoreCase("")){
			double pickuptime =  Double.parseDouble(pickupTime2);
			Log.v(TAG ," pickuptime bfor Round off == "+pickuptime );
			pickuptime = Math.round(pickuptime*100.0)/100.0;
			Log.v(TAG ," pickuptime Aftr Round off == "+pickuptime );

			if(pickuptime >=12){
				if(pickuptime>=13) pickuptime = pickuptime -12.00;
				pickuptime = Math.round(pickuptime*100.0)/100.0;
				returnString = returnString + pickuptime +" PM";
			}else{
				returnString = returnString + pickuptime+" AM";
			}
		}
		Log.v(TAG ," pickuptime [*returnString] in getpickUpTime_toBeDisplayed == "+returnString );
		return returnString;
	}

	/*
	 * This METHOD Total Fare based on the carType & Day/Night selected by user..
	 */
	public double getRouteFare(int estdDistance){

		Log.v(TAG,">> inside getRouteFare <<<<");
		double totalFare = 0;
		double baseFare = 0;
		double ratePerKm = 0;
		
		try{
		//	double time = Double.parseDouble(pickupTime);
			boolean isDay = true;	//(time >=19 && time <=5)? false:true;      //Night Time 7pm -6am(ie y [time<=5] say 5.55)

			if(!FareBean.isBeanEmpty()){
				if(carType.equalsIgnoreCase(Constants.SEDAN) && isDay){
					Log.v(TAG,">> FareBean.getSedan_Day_baseFare() == "+FareBean.getSedan_Day_baseFare());
					baseFare = Double.parseDouble(FareBean.getSedan_Day_baseFare());
					ratePerKm = Double.parseDouble(FareBean.getSedan_Day_ratePerKm());
					totalFare = baseFare + (ratePerKm * estdDistance);

				}else if(carType.equalsIgnoreCase(Constants.SEDAN) && (!isDay)){
					Log.v(TAG,">> FareBean.getSedan_Night_baseFare() == "+FareBean.getSedan_Night_baseFare());
					baseFare = Double.parseDouble(FareBean.getSedan_Night_baseFare());
					ratePerKm =Double.parseDouble(FareBean.getSedan_Night_ratePerKm());
					totalFare = baseFare + (ratePerKm * estdDistance);

				}else if(carType.equalsIgnoreCase(Constants.ECONOMY) && (isDay)){
					Log.v(TAG,">> FareBean.getEconomy_Day_baseFare() == "+FareBean.getEconomy_Day_baseFare());
						baseFare = Double.parseDouble(FareBean.getEconomy_Day_baseFare());
						ratePerKm = Double.parseDouble(FareBean.getEconomy_Day_ratePerKm());
						totalFare = baseFare + (ratePerKm * estdDistance);
				}else if(carType.equalsIgnoreCase(Constants.ECONOMY) && (!isDay)){
					Log.v(TAG,">> FareBean.getEconomy_Night_baseFare() == "+FareBean.getEconomy_Night_baseFare());
					baseFare = Double.parseDouble(FareBean.getEconomy_Night_baseFare());
					ratePerKm = Double.parseDouble(FareBean.getEconomy_Night_ratePerKm());
					totalFare = baseFare + (ratePerKm * estdDistance);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return totalFare;
	}


	private void showMapRoute(Bundle b){
		if(b!=null){
			Intent gotoShowMapPage =  new Intent();
			gotoShowMapPage.setComponent(new ComponentName("com.prabhakar.taxiclubapp", "com.prabhakar.taxiclubapp.LocationMapperActivity"));
			gotoShowMapPage.putExtras(b);
			BookingSummaryActivity.this.startActivity(gotoShowMapPage);

		}else{
			finish();
		}
	}

	private void gotoHomePage(){

	//	new GPSChecker().showAlertDialog(this, "Booking Success", Constants.BOOKING_SUCCESSFULL);

		Intent gotoHomePage =  new Intent();
		gotoHomePage.setComponent(new ComponentName("com.prabhakar.taxiclubapp", "com.prabhakar.taxiclubapp.WelcomeActivity"));
		gotoHomePage.putExtras(b);
		BookingSummaryActivity.this.startActivity(gotoHomePage);

	}


	//Async Class to get RouteDuration [Estimated Time & Distance]....
	private class getRouteDuration extends AsyncTask<Void, Void, Document>{

		Document doc;
		int routeLength;
		int routeTime_inMins;
		private	ProgressDialog pd;
		
		@Override
		protected Document doInBackground(Void... params) {

			Log.v(TAG ,">>>>>>>>>>>  doInBackground of  getRouteDuration  <<<<<<<<<<<<< ");
			try{
				md = new GMapV2Direction();
				doc = md.getDocument(sourceLatlng, destinationLatlng, GMapV2Direction.MODE_DRIVING);
				routeTime_inMins =(int) md.getDurationValue(doc);
				routeLength = (int) md.getMyRouteLength(doc);

				Log.v(TAG ,"time duration >> "+routeTime_inMins +" routeLength >> "+routeLength);

			}catch(Exception e ){
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		
			pd = new ProgressDialog(BookingSummaryActivity.this);
			pd.setMessage("Loading Booking Summary Deatils.. Please wait...");
			pd.setIndeterminate(false);
			pd.show();
		}

		@Override
		protected void onPostExecute(Document result) {
			
			pd.setMessage("Thanks for your patience..");
			pd.dismiss();
			//Method Call Post Async call...
			if(routeLength!=0 && routeTime_inMins!=0){
				showBookingSummary(routeLength, routeTime_inMins);
			}else{
				Toast.makeText(BookingSummaryActivity.this, Constants.ERROR_MESSAGE_TryAgain,Toast.LENGTH_LONG).show();
			}
		}

	}	// Async-Class body ends here ...


	/*
	 * private Class tht runs  the AsynTask
	 */
	private class AsyncBookingRequest extends AsyncTask <String , String, String>{

		private static final String Tag ="AsyncBookingCall";
		private ProgressDialog pDialog;
		int success = 0;
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			Log.v(Tag ,"Inside onPreExecute ");
			pDialog = new ProgressDialog(BookingSummaryActivity.this);
			pDialog.setMessage("Processing Booking details. Please wait...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(true);
			pDialog.show();
		}

		@Override
		protected String doInBackground(String... args) {

			String response = "";
			Log.v(Tag ," >>>>> Inside doInBackground > ");
			// Building Parameters
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair("name", name));
			params.add(new BasicNameValuePair("phoneNumber", phoneNumber));
			params.add(new BasicNameValuePair("email", email));
			params.add(new BasicNameValuePair("pickUpLocation", pickUpLocation));
			params.add(new BasicNameValuePair("destination", dropLocation));
			params.add(new BasicNameValuePair("pickUpDate", pickUpDate));
			params.add(new BasicNameValuePair("pickupTime", pickupTime));
			params.add(new BasicNameValuePair("noOfPassengers", noOfPassengers));
			params.add(new BasicNameValuePair("carType", carType));
			params.add(new BasicNameValuePair("bookingType", Constants.BOOKING_TYPE_P2P));

			// getting JSON Object
			// Note that taxi-Booking url accepts POST method
			JSONObject json = null;				

			// check for success tag
			try {
				json = jsonParser.makeHttpRequest(Constants.TC_RestURL_Booking,"POST", params);
				Log.d("Customer Registration Response", json.toString());

				success = json.getInt(Constants.TAG_SUCCESS);
				response = json.getString(Constants.TAG_MESSAGE);
				if (success == 1) {
					// successfully Booking request..!!!

					//    Intent i = new Intent(getApplicationContext(), WelcomeActivity.class);
					//    startActivity(i);

					// closing this screen
					//finish();
				} else {
					// failed to register customer..!!!
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}catch (Exception e) {
				e.printStackTrace();	
			}

			return response;

		}

		@Override
		protected void onPostExecute(String response) {
			super.onPostExecute(response);

			// dismiss the dialog once Booking request successfull..
			pDialog.setMessage(response);
			pDialog.dismiss();
			if(success==1){
				Toast.makeText(BookingSummaryActivity.this,Constants.BOOKING_SUCCESSFULL, Toast.LENGTH_LONG).show();
				//showMapRoute(b);
				gotoHomePage();	
			}
			//else{---OR--
			//finish();
		}

	}

}
